/**
 * Copyright (c) 2014-2016 www.nryuncang.com. All Rights Reserved.
 */
package com.topisv.tms.service.print.impl;

import static com.google.common.base.Preconditions.checkArgument;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.ExpressConfigure;
import com.topisv.tms.entity.ExpressStyle;
import com.topisv.tms.entity.work.WorkOrder;
import com.topisv.tms.entity.work.WorkTask;
import com.topisv.tms.mybatis.SqlMapDao;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.service.ExpressConfigureService;
import com.topisv.tms.service.LogisticsMailNoService;
import com.topisv.tms.service.work.WorkOrderService;
import com.topisv.tms.service.work.WorkTaskService;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * 申通打印
 *
 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
 * @version 0.0.16
 */
@Component
public class STOPrintServiceImpl extends AbstractPrintService {

	private static final Logger logger = LoggerFactory.getLogger(STOPrintServiceImpl.class);

	private static String create_code = "vip0007";
	
	@Autowired
	private WorkTaskService workTaskService;
	@Autowired
	private ExpressConfigureService expressConfigureService;
	@Autowired
	private SqlMapDao sqlMapDao;
	@Autowired
	private WorkOrderService workOrderService;
	@Autowired
	private LogisticsMailNoService logisticsMailNoService;
	@Autowired
	private EdiOrderDao ediOrderDao;

	@SuppressWarnings("unchecked")
    @Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public List<EdiOrder> doGetExpressNo(List<String> orderNoList, ExpressStyle template, String taskCode) throws Exception {

		// 第一步:得到基础信息如作业任务，订单列表、仓库信息、配置信息
		WorkTask workTask = workTaskService.loadTaskByCode(taskCode);
		ExpressConfigure expressConfigure = expressConfigureService.findByWarehouseAndCompany(workTask.getWarehouseCode(), template.getLogisticsCompany().getCompanyCode());
		
		List<EdiOrder> ediOrderList = sqlMapDao.selectList("ediOrderMapper.getEdiOrderListByOrdeno", orderNoList);
	
		// 第二步:循环订单
		for (EdiOrder ediOrder : ediOrderList) {

			WorkOrder workOrder = workOrderService.loadOrder(ediOrder.getBatchTaskCode(), ediOrder.getOrdeno());
			if (workOrder.getEbillNo() == null || "cbill".equals(workOrder.getBillType())
					|| !template.getLogisticsCompany().getCompanyCode().equals(workOrder.getExpressCompany())) {
				
				// 取号段
//				List<LogisticsMailNo> logisticsMailNos = logisticsMailNoService.getLogisticsMailNo("pending",
//						template.getLogisticsCompany().getCompanyCode(), ediOrder.getWarehouseCode(), 1);
				String mailNo = logisticsMailNoService.getLogisticsMailNo(ediOrder.getOrdeno(), template.getLogisticsCompany().getCompanyCode(), ediOrder.getWarehouseCode());
				
				ediOrder.setMailNo(mailNo);
				
				// 拼装报文
				String content = getSTOXml(ediOrder, expressConfigure);
				logger.info("{}=申通取单号报文={}", ediOrder.getOrdeno(), content);

				
				// 发送天天接口接口,解析返回值，赋值
				String returnData = resturnSTOResult(content, expressConfigure);
				logger.info("{}=申通取单号返回的报文={}", ediOrder.getOrdeno(), returnData);
				
				JSONObject jsons = JSONObject.fromObject(returnData);
				String data = jsons.getString("data");
				if ("true".equals(jsons.getString("success"))) {
					JSONArray jsonArray = JSONArray.fromObject(data);
					List<Map<String, Object>> dataList = (List<Map<String, Object>>) jsonArray;
					if (dataList != null && !dataList.isEmpty()) {
						Map<String, Object> result = dataList.get(0);
						ediOrder.setDestCode(String.valueOf(result.get("bigchar"))); 
						ediOrder.setCacode(template.getLogisticsCompany().getCompanyCode());//快递公司代码
						ediOrder.setCaname(template.getLogisticsCompany().getCompanyName());//快递公司名称
					}
				} else {
					logger.error("{}=获取STO信息失败={}", ediOrder.getOrdeno(),returnData);
					throw new RuntimeException(ediOrder.getOrdeno()+"=获取STO信息失败=");
				}
			}
		}
		ediOrderDao.save(ediOrderList);

		return ediOrderList;
	}

	private String resturnSTOResult(String content, ExpressConfigure expressConfigure) throws Exception {
		
		String url = expressConfigure.getUrl();
		String appKey = expressConfigure.getAppKey();
		String pwd = expressConfigure.getPassword();
		
		// 校验请求地址
		checkArgument(StringUtils.isNotEmpty(url), String.format("STO请求地址 is empty"));
		checkArgument(StringUtils.isNotEmpty(appKey), String.format("STO AppKey is empty"));
		checkArgument(StringUtils.isNotEmpty(pwd), String.format("STO 密码 is empty"));
		
		List<NameValuePair> parameters = new ArrayList<NameValuePair>();
		parameters.add(new BasicNameValuePair("code", create_code));
		parameters.add(new BasicNameValuePair("data_digest", appKey));
		parameters.add(new BasicNameValuePair("cuspwd", pwd));
		parameters.add(new BasicNameValuePair("data", content));
		
		return super.requestExpressNo(url, parameters);
	}

	/**
	 * 
	 * 申通获取单号的报文
	 *
	 * @param order
	 *            订单
	 * @param expressConfigure
	 *            申通的配置信息
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	private String getSTOXml(EdiOrder order, ExpressConfigure expressConfigure) {
		JSONObject jsonObject = new JSONObject();
		// 运单编号 String
		jsonObject.put("billno", order.getMailNo());

		// 寄件日期yyyy-mm-dd String
		jsonObject.put("senddate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

		// 网点名称 String
		jsonObject.put("sendsite", expressConfigure.getCompanyName());

		// 客户名称 String
		jsonObject.put("sendcus", expressConfigure.getWarehouseName());

		// 收件人 String
		jsonObject.put("receiveperson", order.getRecena());

		// 收件人电话 String
		jsonObject.put("receivetel", StringUtils.isNotBlank(order.getMobile()) ? order.getMobile() : order.getTeleph());

		// 备注 String
		jsonObject.put("remark", order.getRemark());

		// 收件省份 String
		jsonObject.put("receiveprovince", order.getProvna());

		// 收件城市 String
		jsonObject.put("receivecity", order.getCityna());

		// 收件地区 String
		jsonObject.put("receivearea", order.getDistna());

		// 收件地址 String
		jsonObject.put("receiveaddress", order.getAddres());

		// 大字 String
		jsonObject.put("bigchar", new StringBuilder().append(order.getProvna()).append(order.getCityna()));

		// 订单号 String
		jsonObject.put("orderno", order.getOrdeno());
		
		JSONArray jsonArray = new JSONArray();
		jsonArray.add(jsonObject);
		
		return jsonArray.toString();

	}
}
